<?php
/**
 * Tiny - A PHP Framework For Web Artisans
 * @author Tiny <tinylofty@gmail.com>
 * @copyright Copyright(c) 2010-2014 http://www.tinyrise.com All rights reserved
 * @version 1.0
 */
/**
 * 插件类
 * 
 * @author Tiny
 * @class Widget
 */
class Widget extends Object
{
	protected $encoding='UTF-8';
	public $cache;
	public $cacheTime;
	private $action;
	private $id;
    /**
     * 构造函数
     * 
     * @access public
     * @param string $id
     * @return mixed
     */
	public function __construct($id='widget')
	{
		$this->id = $id;
	}
    /**
     * 初始化
     * 
     * @access public
     * @return mixed
     */
	public function init()
	{
	}
    /**
     * 执行函数
     * 
     * @access public
     * @return mixed
     */
	public function run()
	{
        
		$method = $this->getAction();
		$args = $this->args;
		if($this->cache == "true")
		{
			$cache = CacheFactory::getInstance();
			$content = $cache->get($method.$args);
			if($content===null)
			{
				ob_start();
				ob_implicit_flush(false);
				$this->doMethod($method,$args);
				$content = ob_get_clean();
				$cache->set($method.$args,$content,intval($this->cacheTime));
			}
			echo $content;
		}
		else $this->doMethod($method,$args);
			
	}
    /**
     * 执行方法
     * 
     * @access global
     * @param mixed $method
     * @param mixed $args
     * @return mixed
     */
    function doMethod($method,$args){
        if(method_exists($this,$method)){
            if($args===null)$this->$method();
            else $this->$method($args);
        }
        else
        {
            $className = $this->id;
            $this->renderFile("$className/$method",$this->output);
        }
    }
    /**
     * 设置action
     * 
     * @access public
     * @param mixed $action
     * @return mixed
     */
	public function setAction($action)
	{
		$this->action = $action;
	}
    /**
     * 取得action
     * 
     * @access public
     * @return mixed
     */
	public function getAction()
	{
		if($this->action===null) $this->setAction(Req::args('act'));
		return $this->action;
	}
    /**
     * 取得ID
     * 
     * @access public
     * @return mixed
     */
	public function getId()
	{
		return $this->id;
	}
    /**
     * 取得视图文件
     * 
     * @access public
     * @param mixed $viewName
     * @return mixed
     */
	public function getViewFile($viewName)
	{
		if(($theme = Tiny::app()->getTheme())!==null)
        {
        	$viewFile = $theme->getBasePath().DIRECTORY_SEPARATOR.'widgets'.DIRECTORY_SEPARATOR.$viewName.'.html';
            if(file_exists($viewFile))return $viewFile;
        }
		return APP_CODE_ROOT.'widgets/'.$viewName.'.html';
	}
    /**
     * 渲染视图
     * 
     * @access public
     * @param mixed $viewFile
     * @param bool $return
     * @return mixed
     */
	public function renderFile($viewFile,$return=false)
	{
		$content=$this->renderInternal($viewFile,$return);
		return $content;
	}
    /**
     * 渲染
     * 
     * @access public
     * @param mixed $viewFile
     * @param bool $return
     * @return mixed
     */
	public function renderInternal($viewFile,$return=false)
	{
		
		$data = $this->properties;
		if(is_array($data))
			extract($data,EXTR_PREFIX_SAME,'data');
		$tplfile  = $this->getViewFile($viewFile);
		if(file_exists($tplfile))
		{
			$runfile= Tiny::app()->getRuntimePath().DIRECTORY_SEPARATOR.'widgets/'.$viewFile.'.php';
			if(!file_exists($runfile) || filemtime($runfile)<filemtime($tplfile))
			{
				$file = new File($runfile,'w+');
				$template = $file->getContents($tplfile);
				$t = new Tag();
				$tem = $t->resolve($template);
				$file->write($tem);
			}
			header("Content-type: text/html; charset=".$this->encoding);
			if($return)
			{
				ob_start();
				ob_implicit_flush(false);
				require($runfile);
				return ob_get_clean();
			}
			else
				require($runfile);
		}
		else
		{
			if($this->id != Tiny::app()->getId())
			{
				 trigger_error("{$this->id}Widget->{$this->getAction()}() not exists",E_USER_ERROR);
			}
			else Tiny::msg('','无法找到请求的页面',404);
		}
	}
    /**
     * 创建插件
     * 
     * @access public
     * @param mixed $className
     * @return mixed
     */
	public static function createWidget($className)
	{
        
		$classWidget = ucfirst($className);
		$classWidget .='Widget';
		if(class_exists($classWidget)) return new $classWidget($className);
		else return new Widget(strtolower($className));
	}
}
